package com.wolfeyes.common.utils.datetime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wolfeyes.common.core.enums.common.DateFormatTypeEnum;

//import oracle.sql.DATE;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期处理工具类
 * 核心思路：
 * 可以使用三种方法更改日历字段：set()、add() 和 roll()。
 * 对于相关操作说明及差异性
 * 详见java-API文档。
 */
public class DateUtilss {
	
    private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);

	/** 
	 * 判断是否润年
	 * 详细设计思路：
	 *  1.被400整除，是闰年，比如2000年，否则：
	 *  2.能被4整除，同时能被100整除，则不是闰年，比如1900年，
	 *  3.能被4整除，同时不能被100整除，则是闰年，比如2004年，
	 *  4.不能被4整除，则不是闰年，比如2001年。
	 *  
	 * @param dateString 字符串型的日期
	 * @return 
	 */  
	public static boolean isLeapYear(String dateString) {
		
		// String 转换 Date；(短日期格式化； "yyyy-MM-dd")
		Date date = DateUtilss.getDate(dateString, DateFormatTypeEnum.SHORTDATE.getValue());
	    
		// 获取公历(格里高里历)的对象实例
	    GregorianCalendar gregorianCalendar = (GregorianCalendar) Calendar.getInstance();
	    
	    gregorianCalendar.setTime(date);
	    
	    int year = gregorianCalendar.get(Calendar.YEAR);
	    
	    // 比如2000年
	    if ((year % 400) == 0) {
	    	
	    	return true; 
	    } else if ((year % 4) == 0) {
	    	
	    	// 比如1900年
	        if ((year % 100) == 0) {
	        	
	        	return false;
	        	
        	// 比如2004年
	        } else {
	        	
	        	return true; 
	        }
	        
        // 比如2001年
	    } else {
	    	
	    	return false;
	    }  
	}
	
    /**
     * 计算距离现在多久，非精确
     *
     * @param date
     * @return
     */
    public static String getTimeBefore(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        } else if (hour > 0) {
            r += hour + "小时";
        } else if (min > 0) {
            r += min + "分";
        } else if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算距离现在多久，精确
     *
     * @param date
     * @return
     */
    public static String getTimeBeforeAccurate(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        }
        if (hour > 0) {
            r += hour + "小时";
        }
        if (min > 0) {
            r += min + "分";
        }
        if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }
    
    /**
     * @Title: Date 转换 String；
     * @Description: 快速获取默认格式的日期
     * @param date 指定的日期
     * @return 返回类型 String
     */
    public static String format(Date date) {
    	
        return DateUtilss.format(date, DateFormatTypeEnum.SHORTDATE.getValue());
    }

    /**
     * @Title: Date 转换 String；
     * @Description: 快速获取自定义格式的日期
     * @param date 指定的日期
     * @param pattern 日期格式
     * @return 返回类型 String
     */
    public static String format(Date date, String pattern) {
    	
        if (date != null) {
        	
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
            
            return simpleDateFormat.format(date);
        }
        
        return null;
    }
    
	/**
	* @Title: Date 转换 String；
	* @Description: TODO(随机生成编号) 
	* @param arg[] 参数说明 
	* @param date 指定的日期
	* @param dateFormat 日期格式
	* @author yanyl
	* @since 2018年07月12日上午11:37:39
	* @return 返回类型 String
	* @throws Exception
	 */
	public static String getDateString(Date date, String dateFormat) {
		
		// 获取简易型的日期格式对象实例
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
		
		// 格式化日期
		return simpleDateFormat.format(date);
	}

	/**
	* @Title: String 转换 Date；
	* @Description: TODO(随机生成编号) 
	* @param arg[] 参数说明 
	* @param dateString 字符串型的日期
	* @param dateFormat 日期格式
	* @author yanyl
	* @since 2018年07月12日上午11:37:39
	* @return 返回类型 Date
	* @throws Exception
	 */
	public static Date getDate(String dateString, String dateFormat) {
		
		// 获取简易型的日期格式对象实例
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
		
		try {
			
			// 解析为日期对象实例
			return simpleDateFormat.parse(dateString);
			
		} catch (ParseException e) {
			
			//LogUtil.ERROR(e.getMessage(), MessageUtil.getMessage(Arrays.toString(e.getStackTrace()), 
			//Thread.currentThread().getStackTrace()[1].getClassName()));
			return null;
		}
	}
	
	/**
	 * @Title: 快速获取系统当前某个日期下前或后几天的日期
	 * @Description: TODO(随机生成编号) 
	 * @param 参数说明
	 * @param date 指定的日期
	 * @param index 正数为后几天，反之负数为前几天
	 * @param dateFormat 日期格式
	 * @author yanyl 
	 * @since 2018年07月12日上午11:37:39
	 * @return 返回类型 Date
	 * @throws Exception
	 */
    public static String getDelayDay(String dateString, String index, String dateFormat) {
    	
		// String 转换 Date；(短日期格式化； "yyyy-MM-dd")
		Date date = DateUtilss.getDate(dateString, DateFormatTypeEnum.SHORTDATE.getValue());
		
		// 获取毫秒数
		long newTime = (date.getTime() / 1000) + Integer.parseInt(index) *24 *60 *60;
		
		// 将给定的毫秒数重新设置此日期对象。
		date.setTime(newTime * 1000);
		
		// Date 转换 String；
		return DateUtilss.getDateString(date, dateFormat);
		
    }
	/**
	 * @Title: 快速获取系统当前某个日期下前或后几天的日期
	 * @Description: TODO(随机生成编号) 
	 * @param 参数说明
	 * @param date 指定的日期
	 * @param index 正数为后几天，反之负数为前几天
	 * @author yanyl 
	 * @since 2018年07月12日上午11:37:39
	 * @return 返回类型 Date
	 * @throws Exception
	 */
    public static Date getDelayDay(Date date, int index) {
    	
    	// 获取公历(格里高里历)的对象实例
        Calendar calendar = new GregorianCalendar();
        
        // 将给定的日历字段Date-设置为给定值。
        calendar.setTime(date);
        
        // 方式一：
        // 将给定的日历字段Date-设置为给定值。
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + index);
        
        // 方式二：
        //calendar.add(Calendar.DATE, index);
        
        // 返回此日历对象所表示时间值的日期对象(Date)
        return calendar.getTime();
    }
    
	/**
	* @Title: 快速获取系统当前月份的开始时间（月初）；
	* @Description: TODO(随机生成编号) 
	* @param 参数说明
	* @param date 当前月份
	* @author yanyl 
	* @since 2018年07月12日上午11:37:39
	* @return 返回类型 Date
	* @throws Exception
	 */
	public static Date getMonthStart(Date date) {
		
		// 获取日历对象实例
        Calendar calendar = Calendar.getInstance();
        
        // 将给定的日历字段Date-设置为给定值。
        calendar.setTime(date);
        
        // 获取日历索引
        int index = calendar.get(Calendar.DAY_OF_MONTH);
        
        // 根据日历的规则，为给定的日历字段添加或减去指定的时间量。
        calendar.add(Calendar.DATE, (1 - index));
        
        // 返回此日历对象所表示时间值的日期对象(Date)
        return calendar.getTime();
    }
	
	/**
	* @Title: 快速获取系统当前年份；
	* @Description: TODO(随机生成编号) 
	* @param 参数说明
	* @author yanyl 
	* @since 2018年07月12日上午11:37:39
	* @return 返回类型 int
	* @throws Exception
	 */
	public static int getYearNow() {
		
		// 方法一：
		//String currentYear = DateUtils.getTimeNow().substring(0, 4);
		
		// 快速获取普通短格式的系统当前日期字符串；
		//String currentYear = DateUtils.getDateString(new Date(), DateFormatTypeEnum.NORMALSHORTDATE.getValue());
		
		// 快速获取系统当前日期；
		Date currentDate = new Date();
		
		// 获取日历对象实例
		Calendar calendar = Calendar.getInstance();
		
		// 将给定的日历字段Date-设置为给定值。
		calendar.setTime(currentDate);
		
		// 方法二：
		// 使用给定的日期 Date 设置此 日历Calendar 的时间。
		
		//返回给定日历字段-年份Year的值
		int currentYear = calendar.get(Calendar.YEAR);
		
		return currentYear;
	}
	
	/**
	* @Title: 快速获取普通短格式的系统当前日期字符串；
	* @see {@link DateFormatTypeEnum #NORMALSHORTDATE}
	* @Description: TODO(随机生成编号) 
	* @param 参数说明
	* @author yanyl 
	* @since 2018年07月12日上午11:37:39
	* @return 返回类型 String
	* @throws Exception
	 */
	public static String getDateNow() {
		
		// 快速获取普通短格式的系统当前日期字符串；
		String currentDate = DateUtilss.getDateString(new Date(), DateFormatTypeEnum.NORMALSHORTDATE.getValue());
		
		return currentDate;
	}
	
	/**
	 * @title 快速获取长格式的系统当前时间字符串；
	 * @see {@link DateFormatTypeEnum #LONGDATE}
	 * @description TODO(随机生成编号)
	 * @param arg 参数说明
	 * @author yanyl
	 * @since 2018年07月12日上午11:37:39
	 * @return 返回类型 String
	 * @throws Exception
	 */
	public static String getTimeNow() {
		
		// 快速获取长格式的系统当前时间字符串；
		String currentTime = DateUtilss.getDateString(new Date(), DateFormatTypeEnum.LONGDATE.getValue());
		
		return currentTime;
	}
	
	/**
	 * 测试方法main()
	 * @param args 参数数组
	 */
	public static void main(String[] args) {
		
		// 快速获取系统当前年份；
		int currentYear = DateUtilss.getYearNow();
		
		// 打印控制台
		System.out.println(currentYear);
		
		// 快速获取普通短格式的系统当前日期字符串；
		String currentDate = DateUtilss.getDateNow();
		
		// 打印控制台
		System.out.println(currentDate);
		
		// 快速获取长格式的系统当前时间字符串；
		String currentTime = DateUtilss.getTimeNow();
		
		// 打印控制台
		System.out.println(currentTime);
		
	}
	
}
